import traceback
from flask import Blueprint, current_app, request, jsonify
from flask_caching import Cache
import akshare as ak
import math
import pandas as pd
from app.models import db, UserAsset, Transaction, UserBehaviorStats
from datetime import datetime

bond_controller = Blueprint('bond_controller', __name__)
cache = Cache(config={'CACHE_TYPE': 'simple'})

@bond_controller.before_app_request
def init_cache():
    cache.init_app(current_app)

@bond_controller.before_request
def log_request():
    current_app.logger.info(f"[BOND] {request.method} {request.url}")

@bond_controller.get('/list')
def get_info():
    """
    GET /bond/list
    返回所有沪深可转债的实时行情数据，字段包括
      symbol,
      name,
      trade,
      pricechange,
      changepercent,
      buy,
      sell,
      settlement,
      open,
      high,
      low,
      amount,
      code,
      ticktime
    """
    cache_key = 'bond_list'
    data=cache.get(cache_key)
    if data:
        current_app.logger.debug(f"[BOND] 从缓存中获取可转债信息")
        return jsonify({'code': 0, 'data': data})
    
    try:
        df=ak.bond_zh_hs_cov_spot()
        df=df.where(pd.notnull(df), None)  # 替换 NaN 为 None   

        current_app.logger.debug(f"[BOND] raw columns = {df.columns.tolist()}")

        records = df.to_dict(orient='records')

        cache.set(cache_key, records, timeout=300)

        return jsonify({'code': 0, 'data': records})
    
    except Exception as e:
        current_app.logger.error(f"[BOND] 获取可转债信息失败: {e}")
        return jsonify({'code': 500, 'msg': str(e)}), 500


@bond_controller.get('/trend')
def get_trend():
    """
    GET /bond/trend
    返回沪深可转债的涨跌幅数据，字段包括
      date,
      open,
      high,
      low,
      close,
      volume
    """
    symbol = request.args.get('symbol')
    if not symbol:
        return jsonify({'code': 1,'msg': '缺少 symbol 参数'}), 400

    cache_key = f'bond_trend_{symbol}'
    data=cache.get(cache_key)
    if data:
        current_app.logger.debug(f"[BOND] 从缓存中获取可转债趋势数据")
        return jsonify({'code': 0, 'data': data})

    try:
        df = ak.bond_zh_hs_cov_daily(symbol=symbol)
        df = df.where(pd.notnull(df), None)  # 替换 NaN 为 None

        current_app.logger.debug(f"[BOND] raw columns = {df.columns.tolist()}")

        records = df.to_dict(orient='records')

        cache.set(cache_key, records, timeout=300)

        return jsonify({'code': 0, 'data': records})

    except Exception as e:
        current_app.logger.error(f"[BOND] 获取可转债趋势数据失败: {e}")
        return jsonify({'code': 500, 'msg': str(e)}), 500

@bond_controller.post('/buy')
def buy_bond():
    """
    POST /api/bond/buy
    购买债券
    请求参数：
    - userid: 用户ID
    - products_id: 债券代码
    - products_name: 债券名称
    - quantity: 购买数量
    - price: 当前价格
    - trade_time: 交易时间
    """
    try:
        data = request.json
        current_app.logger.debug(f"Request JSON: {data}")  # 打印请求的 JSON 数据

        userid = data.get('userid')
        if isinstance(userid, str):
            userid = int(userid)  # 如果 userid 是字符串，转换为整数

        products_id = data.get('products_id')
        products_name = data.get('products_name')
        quantity = data.get('quantity')
        price = data.get('price')

        if not all([userid, products_id, products_name, quantity, price]):
            return jsonify({'code': 1, 'msg': '缺少必要参数'}), 400

        # 设置交易时间为当前时间
        trade_time = datetime.now()
       # 计算交易金额
        trade_amount = float(quantity) * float(price)  # 确保计算结果为浮点数

        # 更新用户资产
        asset = UserAsset.query.filter_by(userid=userid, products_id=products_id).first()
        if asset:
            asset.quantity += quantity
        else:
            asset = UserAsset(
                userid=userid,
                products_id=products_id,
                products_name=products_name,
                type='债券',
                quantity=quantity,
                buy_price=price
            )
            db.session.add(asset)

        # 添加交易记录
        transaction = Transaction(
            userid=userid,
            products_id=products_id,
            products_name=products_name,
            type='债券',
            trade_type='买入',
            quantity=quantity,
            trade_time=trade_time,  # 使用当前时间
            trade_amount=trade_amount
        )
        db.session.add(transaction)
        ##
        behavior_stats = UserBehaviorStats.query.filter_by(user_id=userid).first()
        behavior_stats.total_transactions = UserBehaviorStats.total_transactions + 1
        behavior_stats.total_commission = UserBehaviorStats.total_commission + trade_amount
        ##
        db.session.commit()
        return jsonify({'code': 0, 'msg': '购买成功'}), 200
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"[BOND] 购买债券失败: {e}")
        return jsonify({'code': 1, 'msg': f'购买失败: {str(e)}'}), 500


@bond_controller.post('/sell')
def sell_bond():
    """
    POST /api/bond/sell
    卖出债券
    请求参数：
    - userid: 用户ID
    - products_id: 债券代码
    - products_name: 债券名称
    - quantity: 卖出数量
    - price: 当前价格
    """
    try:
        data = request.json
        userid = data.get('userid')
        products_id = data.get('products_id')
        products_name = data.get('products_name')
        quantity = data.get('quantity')
        price = data.get('price')

        if not all([userid, products_id, products_name, quantity, price]):
            return jsonify({'code': 1, 'msg': '缺少必要参数'}), 400

        trade_time = datetime.now()  # 设置交易时间为当前时间
        # 检查用户资产是否足够
        asset = UserAsset.query.filter_by(userid=userid, products_id=products_id).first()
        if not asset or asset.quantity < quantity:
            return jsonify({'code': 1, 'msg': '持仓不足，无法卖出'}), 400

        # 计算交易金额
        trade_amount = quantity * price

        # 更新用户资产
        asset.quantity -= quantity
        if asset.quantity == 0:
            db.session.delete(asset)

        # 添加交易记录
        transaction = Transaction(
            userid=userid,
            products_id=products_id,
            products_name=products_name,
            type='债券',
            trade_type='售出',
            quantity=quantity,
            trade_amount=trade_amount,
            trade_time=trade_time
        )
        db.session.add(transaction)
        ##
        behavior_stats = UserBehaviorStats.query.filter_by(user_id=userid).first()
        behavior_stats.total_transactions = UserBehaviorStats.total_transactions + 1
        behavior_stats.total_commission = UserBehaviorStats.total_commission + trade_amount
        ##
        db.session.commit()
        return jsonify({'code': 0, 'msg': '卖出成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 1, 'msg': f'卖出失败: {str(e)}'}), 500